﻿/*!
 *  @brief     创建UdpSocket线程（创建线程的一）- 组播
 *  @details   组播模式（multicast）
 *  @author    YZG
 *  @version   1.0
 *  @date      2019-05-22
 *  @warning
 *  @copyright
 *  @note      UDP客户端加入到另一个组播IP地址的多播组，成员向组播地址发送的数据报，其加入组播的所有成员都可以接收到，类似于QQ群功能。QUdpSocket::joinMulticastGroup()函数实现加入多播组的功能。
 */
#ifndef MULTICASTUDPSOCKETTASK_H
#define MULTICASTUDPSOCKETTASK_H

#include "common_global.h"

#include <QObject>
#include <QAbstractSocket>
#include <QUdpSocket>
#include <QHostAddress>

#define UDPMULTICAST_REPLY_TIMEOUT   3000

namespace Common {

	class COMMONSHARED_EXPORT UdpMulticast : public QObject
	{
		Q_OBJECT
	public:
		explicit UdpMulticast(QObject *parent = Q_NULLPTR);
		~UdpMulticast();

	public:
		/**
		 * @brief getUdpSocket
		 * @return
		 */
		QUdpSocket * getUdpSocket();

		/**
		 * @brief creataMulticast 创建UDP
		 * @param groupIp 组播IP 组播的地址范围: 239.0.0.0～239.255.255.255
		 * @param groupPort 组播端口
		 * @return
		 */
		bool creataMulticast(QString groupIp, int groupPort);

		/**
		 * @brief closeMulticast 退出组播
		 * @return
		 */
		bool closeMulticast();

		/**
		 * @brief sendUdpMsg 发送消息
		 * @param buff 发送的消息
		 * @return
		 */
		bool sendMulticastMsg(QByteArray buff);

		/**
		 * @brief recvMulticastMsg 接收消息
		 * @param sourceIp  发送数据报的源地址
		 * @param sourcePort 发送数据报的源端口号
		 * @param message 接收的数据
		 * @param replyTime 回复时间
		 * @return
		 */
		bool recvMulticastMsg(QString &sourceIp, int &sourcePort, QByteArray &message, const int replyTime = UDPMULTICAST_REPLY_TIMEOUT);

		/**
		 * @brief sendAndRecvMulticastMsg 发送和接收消息
		 * @param sendMsg   发送的消息
		 * @param sourceIp  发送数据报的源地址
		 * @param sourcePort 发送数据报的源端口号
		 * @param recvMsg   接收的数据
		 * @param replyTime
		 * @return
		 */
		bool sendAndRecvMulticastMsg(QByteArray sendMsg, QString &sourceIp, int &sourcePort, QByteArray &recvMsg, const int replyTime = UDPMULTICAST_REPLY_TIMEOUT);

	signals:
		/**
		 * @brief signalRecvMulticastMsg 触发组播的接收的消息
		 * @param sourceIp
		 * @param sourcePort
		 * @param recvMsg
		 */
		void signalRecvMulticastMsg(QString sourceIp, int sourcePort, QByteArray recvMsg);

		public slots:
		/**
		 * @brief slotMulticastReadyRead 读取组播Socket信息
		 */
		void slotMulticastReadyRead();

		/**
		 * @brief slotSocketStateChange 查看网络连接状态
		 * @param state
		 */
		void slotSocketStateChange(QAbstractSocket::SocketState state);

	private:
		QUdpSocket *m_pUdpSocket;               // 组播模式
		QHostAddress m_groupIp;                 // 组播Ip
		quint16 m_groupPort;                    // 组播端口
		bool m_bJoinMulticast;                  // 加入组播状态
	};

} //

#endif // MULTICASTUDPSOCKETTHREAD_H
